// Copyright (c) 2005  INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of cgal-python; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; version 2.1 of the License.
// See the file LICENSE.LGPL distributed with cgal-python.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $Id: Py_Point_2.cpp 167 2007-11-02 15:36:54Z spion $
// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal-python/trunk/cgal-python/bindings/Kernel/Py_Point_2.cpp $
//
// Author(s)     : Naceur Meskini
//=========================================================================

#include <CGAL/basic.h>
#include <include/Kernels.h>

#include <boost/python.hpp>
#include <boost/cstdint.hpp>

const char* Point_2_doc[] =
{
"An object of the class Point_2 is a point in the two-dimensional Euclidean plane ExE.\n",
"x(self) -> returns the Cartesian  x coordinate, that is hx/hw.\n",
"y(self) -> returns the Cartesian  y coordinate, that is hy/hw.\n",
"hx(self) -> returns the homogeneous x coordinate.\n",
"hy(self) -> returns the homogeneous y coordinate.\n",
"hw(self) -> returns the homogenizing coordinate.\n",
"dimension(self) -> returns the dimension (the constant 2).\n",
"homogeneous(self,i) -> returns the i'th homogeneous coordinate of p, starting with 0.Precondition: 0 <= i <= 2.\n",
"bbox(self) -> returns a bounding box containing p.\n"\
"Note that bounding boxes are not parameterized with whatsoever.\n",
"p[i] -> returns cartesian(i).Precondition: 0 <= i <= 1.\n",
"cartesian(self,i) -> returns the i'th Cartesian  coordinate of p, starting with 0.\nPrecondition: 0 <= i <= 1.\n",
"transform(self,Aff_transformation_2 t) -> returns the point obtained by applying t on p.\n"
};

template<class Point_2>
boost::python::str py_repr_Point_2(const Point_2& pt )
{
	using namespace boost::python;
	return str("Point_2("+ str(pt.x()) +","+ str(pt.y()) +")" );
}

template<class kernel>
void Py_Point_2()
{
	typedef typename kernel::Point_2 							Point_2;
 	typedef typename kernel::Vector_2 							Vector_2;
 	typedef typename kernel::FT 								FT;
	typedef typename kernel::RT								RT;

	using namespace boost::python;

        class_< Point_2 >("Point_2", Point_2_doc[0], init<>())
        .def(init< const Point_2& >())
        .def(init< const CGAL::Origin& >())
        .def(init< const FT&, const FT& >())
	.def(init< const FT&, const FT&, const FT& >())
        .def(init< const double&, const double& >())
       	.def(init< const double&, const double&, const double& >())
#if CGAL_VERSION_NR < 1030301000
        .def("x", &Point_2::x, by_cref(), Point_2_doc[1])
        .def("y", &Point_2::y, by_cref(), Point_2_doc[2])
        .def("cartesian", &Point_2::cartesian, by_cref(), Point_2_doc[10])
        .def("hx", &Point_2::hx, by_cref(), Point_2_doc[3])
        .def("hy", &Point_2::hy, by_cref(), Point_2_doc[4])
        .def("hw", &Point_2::hw, by_cref(), Point_2_doc[5])
#else
        .def("x", &Point_2::x, typename Value_or_cref<typename kernel::Compute_x_2, Point_2 > ::type(), Point_2_doc[1])
        .def("y", &Point_2::y, typename Value_or_cref<typename kernel::Compute_y_2, Point_2 > ::type(), Point_2_doc[2])
        .def("cartesian", &Point_2::cartesian, typename Value_or_cref<typename kernel::Compute_x_2, Point_2 > ::type(), Point_2_doc[10])
        .def("hx", &Point_2::hx, typename Value_or_cref<typename kernel::Compute_hx_2, Point_2 > ::type(), Point_2_doc[3])
        .def("hy", &Point_2::hy, typename Value_or_cref<typename kernel::Compute_hy_2, Point_2 > ::type(), Point_2_doc[4])
        .def("hw", &Point_2::hw, typename Value_or_cref<typename kernel::Compute_hx_2, Point_2 > ::type(), Point_2_doc[5])
#endif
        .def("dimension", &Point_2::dimension, Point_2_doc[6])
#if CGAL_VERSION_NR < 1030301000
        .def("homogeneous", &Point_2::homogeneous, by_cref(), Point_2_doc[7])
#else
        .def("homogeneous", &Point_2::homogeneous, typename Value_or_cref<typename kernel::Compute_hx_2, Point_2 > ::type(), Point_2_doc[7])
#endif
        .def("bbox", &Point_2::bbox, Point_2_doc[8])
#if CGAL_VERSION_NR < 1030301000
	.def("__getitem__", &Point_2::operator[], by_cref(), Point_2_doc[9])
#else
	.def("__getitem__", &Point_2::operator[], typename Value_or_cref<typename kernel::Compute_x_2, Point_2 > ::type(), Point_2_doc[9])
#endif
	.def("__repr__", &py_repr_Point_2<Point_2>)
	.def("transform", &Point_2::transform, Point_2_doc[11])
	.def(self == self)
	.def(self != self)
	.def(self < self)
	.def(self > self)
	.def(self <= self)
	.def(self >= self)
	.def(self + Vector_2())
	.def(self - self)
	.def(self - Vector_2())
	.def(self - CGAL::Origin())
    ;
}

void export_Point_2()
{
	Py_Point_2<K>();
}
